/*
 * @Author: hongbin
 * @Date: 2023-03-27 18:58:01
 * @LastEditors: hongbin
 * @LastEditTime: 2023-03-28 16:28:55
 * @Description:粒子效果
 */
import { ParticleEffect } from "@/src/components/particleEffects/ParticleEffect";
import Layout from "@/src/components/Three/Layout";
import { ThreeHelper } from "@/src/ThreeHelper";
import { FC } from "react";
import styled from "styled-components";
import * as THREE from "three";

interface IProps {}

const Physics: FC<IProps> = () => {
    return (
        <>
            <Layout
                seoTitle="粒子效果"
                title={"自定义shader - 粒子效果"}
                init={init}
                destroy={destroy}
                desc={"three.hongbin.xyz"}
            />
        </>
    );
};

export default Physics;

const destroyEvents = [] as Array<VoidFunction>;

function destroy() {
    destroyEvents.forEach((f) => f());
}

async function init(helper: ThreeHelper) {
    // helper.addAxis();
    helper.addStats();
    helper.camera.position.set(0, 0, 50);
    helper.frameByFrame();
    helper.addGUI();
    const mask = document.createElement("div") as HTMLDivElement;
    mask.style["width"] = "100vw";
    mask.style["height"] = "100vh";
    mask.style["position"] = "fixed";
    mask.style["top"] = "0px";
    mask.style["left"] = "0px";
    mask.style["zIndex"] = "2";
    document.body.appendChild(mask);

    const particle = new ParticleEffect(400, new THREE.Color("#fffae5"), 100);
    helper.add(particle.particle);

    const particleEffect = new ParticleEffect(100000, new THREE.Color("#fff"));

    const gltf = await helper.loadGltf("/models/particle1.glb");
    console.log(gltf);
    const HoneyComb = gltf.scene.getObjectByName("HoneyComb") as Mesh;
    const Worm_Gear = gltf.scene.getObjectByName("Worm_Gear") as Mesh;
    const people = gltf.scene.getObjectByName("people") as Mesh;
    const Wall = gltf.scene.getObjectByName("Wall") as Mesh;

    if (!HoneyComb) {
        throw new Error("not HoneyComb");
    }
    if (!Worm_Gear) {
        throw new Error("not Worm_Gear");
    }
    if (!people) {
        throw new Error("not people");
    }
    if (!Wall) {
        throw new Error("not Wall");
    }
    const consoles = {
        list: [
            {
                geometry: Wall.geometry
                    .scale(1.5, 1.5, 1.5)
                    .translate(0, -13, 0),
                color: new THREE.Color("#11dfff"),
            },
            {
                geometry: HoneyComb.geometry.scale(3, 3, 3),
                color: new THREE.Color("#0614d8"),
            },
            {
                geometry: Worm_Gear.geometry.scale(3, 3, 3),
                color: new THREE.Color("#11ff90"),
            },
            {
                geometry: people.geometry
                    .scale(2, 2, 2)
                    .rotateX(0.12)
                    .rotateY(0.82),
                color: new THREE.Color("#3904f9"),
            },
        ],
        curr: -1,
        toggle: () => {
            consoles.progress = 0;
            consoles.curr %= consoles.list.length;
            const effect = consoles.list[consoles.curr];
            particleEffect.to(effect.geometry, effect.color);
            consoles.curr++;
        },
        progress: 0,
    };

    helper.gui?.add(consoles, "toggle");
    helper.gui?.add(consoles, "progress", 0, 1).onChange((v) => {
        particleEffect.setProgress(v);
    });

    helper.animation(() => {
        // if (consoles.progress >= 1) {
        //     consoles.toggle();
        // }
        // consoles.progress += 0.01;
        // particleEffect.setProgress(consoles.progress);

        particle.particle.rotation.y += 0.001;
        particle.particle.rotation.x += 0.001;
    });

    helper.add(particleEffect.particle);
    const height = innerHeight * (consoles.list.length + 1) - 1;
    document.body.style.height = height + "px";

    consoles.list[-1] = {
        geometry: new THREE.BufferGeometry().setAttribute(
            "position",
            new THREE.BufferAttribute(particleEffect.initPosition, 3)
        ),
        color: particleEffect.initColor,
    };

    let curr = 0;
    particleEffect.to(consoles.list[0].geometry, consoles.list[0].color);
    // 滚动控制动画
    const onScroll = () => {
        const currentScrollHeight =
            window.scrollY || document.documentElement.scrollTop;
        const percent = currentScrollHeight / innerHeight;
        const currIndex = Math.floor(percent);
        const progress = percent - Math.floor(percent);

        if (currIndex !== curr) {
            console.log(`${curr} -> ${currIndex}`);
            if (currIndex > curr) {
                particleEffect.translate(
                    consoles.list[curr],
                    consoles.list[currIndex]
                );
            } else {
                particleEffect.translate(
                    consoles.list[currIndex - 1],
                    consoles.list[curr - 1]
                );
            }
            curr = currIndex;
        }
        particleEffect.setProgress(progress);
    };

    document.addEventListener("scroll", onScroll);

    destroyEvents.push(() => {
        document.removeEventListener("scroll", onScroll);
        window.scrollTo({ left: 0, top: 0 });
    });
}
